#ifdef WIN32

#include "Containers/Vector.h"
#include "WindowsDropTarget.h"
#include "WindowsThread.h"

HRESULT STDMETHODCALLTYPE SWindowsDropTarget::DragEnter(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
{
    //check if the data object contains a file
    FORMATETC FormatEtc;
    FormatEtc.cfFormat = CF_HDROP;
    FormatEtc.ptd = nullptr;
    FormatEtc.dwAspect = DVASPECT_CONTENT;
    FormatEtc.lindex = -1;
    FormatEtc.tymed = TYMED_HGLOBAL;

    STGMEDIUM StgMedium;
    HRESULT Result = pDataObj->GetData(&FormatEtc, &StgMedium);

    if (Result == S_OK)
    {
        //get the file name
        WCHAR FileName[MAX_PATH];
        UINT FileCount = DragQueryFile((HDROP)StgMedium.hGlobal, 0xFFFFFFFF, nullptr, 0);
        
        TVector<SPath> Files;
        Files.Reserve(FileCount);

        for (UINT i = 0; i < FileCount; i++)
        {
            ::DragQueryFileW((HDROP)StgMedium.hGlobal, i, FileName, MAX_PATH);
            
            Files.Add(CString((char16_t*)FileName));
        }

        bIsDraggingFile=true;
        CWindowsOSThread::Get()->OnDragFileEnter(Hwnd,Files);
        
        //release the data
        ::ReleaseStgMedium(&StgMedium);
    }

    return S_OK;
}

HRESULT STDMETHODCALLTYPE SWindowsDropTarget::DragOver(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
{
    if(bIsDraggingFile)
    {
        CWindowsOSThread::Get()->OnDragFileOver();
    }
    return S_OK;
}

HRESULT STDMETHODCALLTYPE SWindowsDropTarget::DragLeave()
{
    if(bIsDraggingFile)
    {
        bIsDraggingFile=false;
        CWindowsOSThread::Get()->OnDragFileLeave();
    }

    return S_OK;
}
HRESULT STDMETHODCALLTYPE SWindowsDropTarget::Drop(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
{
    //generate drop event
    if(bIsDraggingFile)
    {
        CWindowsOSThread::Get()->OnFiledDroped();
    }

    return S_OK;
}
#endif
